package com.smartsaas.ugclivii.ui;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.smartsaas.ugclivii.BootStrap;
import com.smartsaas.ugclivii.cd.*;
import com.smartsaas.ugclivii.entity.BomConfig;
import com.smartsaas.ugclivii.entity.Config;
import com.smartsaas.ugclivii.handler.*;
import com.smartsaas.ugclivii.loader.JsonLoader;
import lombok.Data;
import nxopen.*;
import nxopen.blockstyler.BlockDialog;
import nxopen.blockstyler.Node;
import nxopen.blockstyler.Tree;
import nxopen.layer.LayerManager;
import nxopen.layer.State;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class UiContext implements BlockDialog.Initialize{
    //class members
    public static Session SESSION = null;
    public static UFSession UF_SESSION = null;
    public static UI UI = null;
    private nxopen.blockstyler.BlockDialog dialog;
    private nxopen.blockstyler.StringBlock partNumber;// Block type: String
    private nxopen.blockstyler.Explorer explorer;// Block type: Explorer
    private nxopen.blockstyler.Group userUi;// Block type: Group
    private nxopen.blockstyler.TabControl tabControl;// Block type: Tabs Page
    private nxopen.blockstyler.Group loginUi;// Block type: Group
    private nxopen.blockstyler.StringBlock userInput;// Block type: String
    private nxopen.blockstyler.StringBlock passInput;// Block type: String
    private nxopen.blockstyler.Button loginButton;// Block type: Button
    private nxopen.blockstyler.Group codeUi;// Block type: Group
    private nxopen.blockstyler.StringBlock codeInput;// Block type: String
    private nxopen.blockstyler.Button codeButton;// Block type: Button
    private nxopen.blockstyler.Group designUi;// Block type: Group
    private nxopen.blockstyler.Toggle layerHidden;// Block type: Toggle
    private nxopen.blockstyler.Tree designTree;// Block type: Tree Control
    private nxopen.blockstyler.Button designUploadButton;// Block type: Button
    private nxopen.blockstyler.Group mlUi;// Block type: Group
    private nxopen.blockstyler.BodyCollector mlSelection;// Block type: Body Collector
    private nxopen.blockstyler.Tree mlTree;// Block type: Tree Control
    private nxopen.blockstyler.SpecifyCSYS mlCsy;// Block type: Specify Csys
    private nxopen.blockstyler.Button mlUpload;// Block type: Button
    private nxopen.blockstyler.Group bomUi;// Block type: Group
    private nxopen.blockstyler.BodyCollector bomSelection;// Block type: Selection
    private nxopen.blockstyler.Tree bomTree;// Block type: Tree Control
    private nxopen.blockstyler.SpecifyCSYS bomCsy;// Block type: Specify Csys
    private nxopen.blockstyler.Button bomUploadButton;// Block type: Button
    private nxopen.blockstyler.Group eleUi;// Block type: Group
    private nxopen.blockstyler.BodyCollector eleSelection;// Block type: Selection
    private nxopen.blockstyler.SpecifyCSYS eleCsy;
    private nxopen.blockstyler.Tree eleTree;// Block type: Tree Control
    private nxopen.blockstyler.Button eleUploadButton;// Block type: Button
    private nxopen.blockstyler.Group settingUi;// Block type: Group
    private nxopen.blockstyler.FolderSelection workDir;
    private nxopen.blockstyler.FileSelection hostSttingFile;// Block type: NativeFileBrowser
    private nxopen.blockstyler.FileSelection bomSettingFile;// Block type: NativeFileBrowser
    private nxopen.blockstyler.Group workLogUi;// Block type: Group
    private nxopen.blockstyler.StringBlock ribaoTitle;// Block type: String
    private nxopen.blockstyler.MultilineString ribaoContent;// Block type: Multiline String
    private nxopen.blockstyler.Button ribaoButton;// Block type: Button
    private ListingWindow logs;// Block type: Group
    private nxopen.blockstyler.Group stateGroup;// Block type: Group
    private nxopen.blockstyler.ListBox jobBox;// Block type: List Box
    private nxopen.blockstyler.Tree jobTree;// Block type: Tree Control
    private nxopen.blockstyler.Toggle DeBug;// Block type: Toggle
    private nxopen.blockstyler.Toggle wcsAuto;// Block type: Toggle
    private nxopen.blockstyler.DoubleBlock releaseX;// Block type: Double
    private nxopen.blockstyler.DoubleBlock releaseY;// Block type: Double
    private nxopen.blockstyler.DoubleBlock releaseZ;// Block type: Double
    private nxopen.blockstyler.DoubleBlock mlrx;// Block type: Double
    private nxopen.blockstyler.DoubleBlock mlry;// Block type: Double
    private nxopen.blockstyler.DoubleBlock mlrz;// Block type: Double

    private Map<String, List<BomConfig>> bomConfig;

    private Config config;

    private String partNumberCache;


    private static UiContext instance;
    public static UiContext getInstance(){
        return instance;
    }

    public UiContext()throws Exception, RemoteException{
        instance=this;
        try {
            SESSION=(Session) SessionFactory.get("Session");
            UF_SESSION=(UFSession) SessionFactory.get("UFSession");
            UI=(nxopen.UI) SessionFactory.get("UI");
            logs = SESSION.listingWindow();
            dialog = UI.createDialog("MYB2.dlx");
            dialog.addUpdateHandler(new UpdateImpl());
            //dialog.addFilterHandler(new FilterIml());
            dialog.addInitializeHandler(this);
            //dialog.addFocusNotifyHandler(new FocusNotifyImpl());
            //dialog.addKeyboardFocusNotifyHandler(new KeyboardFocusNotifyImpl());
            dialog.addDialogShownHandler(new DialogShownImpl());
        }catch (Exception ex){
            UI.nxmessageBox().show("系统提示",nxopen.NXMessageBox.DialogType.ERROR, ex.getMessage());
        }
    }
    public int show() throws NXException, RemoteException
    {
        try
        {
            dialog.show();
        }
        catch(Exception ex)
        {
            UI.nxmessageBox().show("系统提示", nxopen.NXMessageBox.DialogType.ERROR, ex.getMessage());
        }
        return 0;
    }
    public void dispose() throws NXException, RemoteException
    {
        if(dialog != null)
        {
            dialog.dispose();
            dialog = null;
            instance=null;
        }
    }
    public  void init() throws NXException, RemoteException {
        explorer.setNotifyNodeSelectedPostHandler(new ExplorerNodeSelectedPostHandler());
        designTree.setOnStateChangeHandler(new DesignTreeStateChangeHandler());
        designTree.setAskEditControlHandler(new DesignTreeAskEditControlHandler());
        designTree.setOnEditOptionSelectedHandler(new DesignTreeEditOptionSelectedHandler());
        designTree.setOnSelectHandler(new DesignTreeSelectHandler());
        mlTree.setOnEndLabelEditHandler(new MlTreeEndLabelEditHandler());
        mlTree.setOnBeginLabelEditHandler(new MlTreeBeginLabelEditHandler());
        mlTree.setAskEditControlHandler(new MlTreeAskEditControlHandler());
        mlTree.setOnEditOptionSelectedHandler(new MlTreeEditOptionSelectedHandler());
        mlTree.setOnStateChangeHandler(new MlTreeStateChangeHandler());
        mlTree.setOnSelectHandler(new MlTreeSelectHandler());
        mlTree.setOnMenuHandler(new MlTreeMenuHandler());
        mlTree.setOnMenuSelectionHandler(new MlTreeMenuSelectionHandler());
        eleTree.setOnSelectHandler(new EleTreeSelectHandler());
        EleTreeHandler eleTreeHandler = new EleTreeHandler();
        eleTree.setOnEndLabelEditHandler(eleTreeHandler);
        eleTree.setOnBeginLabelEditHandler(eleTreeHandler);
        eleTree.setAskEditControlHandler(eleTreeHandler);
        eleTree.setOnEditOptionSelectedHandler(eleTreeHandler);
        eleTree.setOnStateChangeHandler(eleTreeHandler);
        eleTree.setOnMenuHandler(eleTreeHandler);
        eleTree.setOnMenuSelectionHandler(eleTreeHandler);
        BomTreeHandler bomTreeHandler = new BomTreeHandler();
        bomTree.setOnSelectHandler(bomTreeHandler);
        bomTree.setOnEndLabelEditHandler(bomTreeHandler);
        bomTree.setOnBeginLabelEditHandler(bomTreeHandler);
        bomTree.setAskEditControlHandler(bomTreeHandler);
        bomTree.setOnEditOptionSelectedHandler(bomTreeHandler);
        bomTree.setOnStateChangeHandler(bomTreeHandler);
        bomTree.setOnMenuHandler(bomTreeHandler);
        bomTree.setOnMenuSelectionHandler(bomTreeHandler);

        String fullPath = SESSION.parts().work().fullPath();
        String pNumber= fullPath.substring(fullPath.lastIndexOf("\\")+1,fullPath.lastIndexOf("."));
        partNumber.setRetainValue(false);
        partNumber.setValue(pNumber);

        //初始化工作目录和目录中配置文件地址
        String s = localDir();
        workDir.setPath(s);
        File bomSetting = new File(s, "bom.json");
        bomSettingFile.setPath(bomSetting.getAbsolutePath());
        File config = new File(s, "config.json");
        hostSttingFile.setPath(config.getAbsolutePath());
        //初始化BOM配置
        loadBomSetting();
        //初始化软件配置
        loadConfig();
    }

    @Override
    public void initialize() throws NXException, RemoteException {
        //初始化逻辑
        partNumber = (nxopen.blockstyler.StringBlock)dialog.topBlock().findBlock("partNumber");
        explorer = (nxopen.blockstyler.Explorer)dialog.topBlock().findBlock("explorer");
        userUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("userUi");
        tabControl = (nxopen.blockstyler.TabControl)dialog.topBlock().findBlock("tabControl");
        loginUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("loginUi");
        userInput = (nxopen.blockstyler.StringBlock)dialog.topBlock().findBlock("userInput");
        passInput = (nxopen.blockstyler.StringBlock)dialog.topBlock().findBlock("passInput");
        loginButton = (nxopen.blockstyler.Button)dialog.topBlock().findBlock("loginButton");
        codeUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("codeUi");
        codeInput = (nxopen.blockstyler.StringBlock)dialog.topBlock().findBlock("codeInput");
        codeButton = (nxopen.blockstyler.Button)dialog.topBlock().findBlock("codeButton");
        designUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("designUi");
        layerHidden = (nxopen.blockstyler.Toggle)dialog.topBlock().findBlock("layerHidden");
        designTree = (nxopen.blockstyler.Tree)dialog.topBlock().findBlock("designTree");
        designUploadButton = (nxopen.blockstyler.Button)dialog.topBlock().findBlock("designUploadButton");
        mlUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("mlUi");
        mlSelection = (nxopen.blockstyler.BodyCollector)dialog.topBlock().findBlock("mlSelection");
        mlTree = (nxopen.blockstyler.Tree)dialog.topBlock().findBlock("mlTree");
        mlCsy = (nxopen.blockstyler.SpecifyCSYS)dialog.topBlock().findBlock("mlCsy");
        mlUpload = (nxopen.blockstyler.Button)dialog.topBlock().findBlock("mlUpload");
        bomUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("bomUi");
        bomSelection = (nxopen.blockstyler.BodyCollector)dialog.topBlock().findBlock("bomSelection");
        bomTree = (nxopen.blockstyler.Tree)dialog.topBlock().findBlock("bomTree");
        bomCsy = (nxopen.blockstyler.SpecifyCSYS)dialog.topBlock().findBlock("bomCsy");
        bomUploadButton = (nxopen.blockstyler.Button)dialog.topBlock().findBlock("bomUploadButton");
        eleUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("eleUi");
        eleSelection = (nxopen.blockstyler.BodyCollector)dialog.topBlock().findBlock("eleSelection");
        eleTree = (nxopen.blockstyler.Tree)dialog.topBlock().findBlock("eleTree");
        eleCsy = (nxopen.blockstyler.SpecifyCSYS)dialog.topBlock().findBlock("eleCsy");
        eleUploadButton = (nxopen.blockstyler.Button)dialog.topBlock().findBlock("eleUploadButton");
        settingUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("settingUi");
        workDir = (nxopen.blockstyler.FolderSelection)dialog.topBlock().findBlock("workDir");
        hostSttingFile = (nxopen.blockstyler.FileSelection)dialog.topBlock().findBlock("hostSttingFile");
        bomSettingFile = (nxopen.blockstyler.FileSelection)dialog.topBlock().findBlock("bomSettingFile");
        workLogUi = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("workLogUi");
        ribaoTitle = (nxopen.blockstyler.StringBlock)dialog.topBlock().findBlock("ribaoTitle");
        ribaoContent = (nxopen.blockstyler.MultilineString)dialog.topBlock().findBlock("ribaoContent");
        ribaoButton = (nxopen.blockstyler.Button)dialog.topBlock().findBlock("ribaoButton");
        stateGroup = (nxopen.blockstyler.Group)dialog.topBlock().findBlock("stateGroup");
        jobTree = (nxopen.blockstyler.Tree)dialog.topBlock().findBlock("jobTree");
        DeBug = (nxopen.blockstyler.Toggle)dialog.topBlock().findBlock("DeBug");
        wcsAuto = (nxopen.blockstyler.Toggle)dialog.topBlock().findBlock("wcsAuto");
        releaseX = (nxopen.blockstyler.DoubleBlock)dialog.topBlock().findBlock("release_x");
        releaseY = (nxopen.blockstyler.DoubleBlock)dialog.topBlock().findBlock("release_y");
        releaseZ = (nxopen.blockstyler.DoubleBlock)dialog.topBlock().findBlock("release_z");
        mlrx = (nxopen.blockstyler.DoubleBlock)dialog.topBlock().findBlock("mlrx");
        mlry = (nxopen.blockstyler.DoubleBlock)dialog.topBlock().findBlock("mlry");
        mlrz = (nxopen.blockstyler.DoubleBlock)dialog.topBlock().findBlock("mlrz");
        this.init();
    }

    public void debug(String msg) {
        try {
            if (DeBug.value()) {
                if (!logs.isOpen()){
                    logs.open();
                }
                logs.writeLine(msg);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    public void debug(Exception e) {
        try {
            if (DeBug.value()) {
                if (!logs.isOpen()){
                    logs.open();
                }
                logs.writeLine(String.format("【Exception】: %s",e.getLocalizedMessage()));
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    public static void loadBomSetting(){
        try{
            String path = instance.bomSettingFile.path();
            UiContext.getInstance().debug("加载BOM配置:"+path);
            if (StringUtils.isNotBlank(path)) {
                List<BomConfig> bomConfigList = JsonLoader.loadJsonList(path, BomConfig.class);
                if (bomConfigList!=null&& CollectionUtil.isNotEmpty(bomConfigList)){
                    instance.bomConfig =new HashMap<>();
                    for (BomConfig config : bomConfigList) {
                        instance.bomConfig.put(config.getName(), config.getChild());
                    }
                }
            }
        }catch (Exception e){
            getInstance().debug(e);
        }
    }
    public static void loadConfig(){
        try{
            String path = instance.hostSttingFile.path();
            UiContext.getInstance().debug("加载软件配置:"+path);
            if (StringUtils.isNotBlank(path)) {
                Config config = JsonLoader.loadJson(path, Config.class);
                if (config!=null){
                    instance.config = config;
                }
            }
        }catch (Exception e){
            getInstance().debug(e);
        }
    }

    public void debugFormat(String p, Object... q) throws RemoteException, NXException{
        if (q!=null){
            String format = String.format(p, q);
            debug(format);
        }
    }

    public static String localDir() {
        try {
            URL location = BootStrap.class.getProtectionDomain().getCodeSource().getLocation();
            File jar = new File(location.toURI());
            File dir = jar.getParentFile();
            return  dir.getAbsolutePath();
        }catch (Exception e){
            UiContext.getInstance().debug(e);
        }
        return null;
    }
}
